package com.zzw.java.serial;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.fazecast.jSerialComm.SerialPort;
import com.zzw.java.service.LevelResultService;
import com.zzw.java.service.impl.SerialPortServiceImp;
import com.zzw.java.mqtt.MqttGateway;
import com.zzw.java.mqtt.MqttInBoundConfiguration;
import com.zzw.java.entity.LevelResult;
import com.zzw.java.pojo.ResponseDataBo;
import com.zzw.java.pojo.UploadDataBo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 接收数据处理
 *
 * @Author：hcy
 * @Package：com.zzw.java.serial.spring
 * @version：1.0
 * @Date：2025/8/7 14:27
 */


@Component
@Slf4j
public class ReceiveDataHandlerImpl implements ReceiveDataHandler {

    // 最大通道号
    private int maxPassage = 32;

    public static String TRANSFER_MODULE_MAC = "";

    public static final int DATA_TYPE = 2;

    public static ArrayList<String> surveyDataList = new ArrayList<>(Collections.nCopies(32, null));

    // 测量数据固定命令
    private final String fixedCommand = "21";

    public static int passage = 2;

    @Resource
    private MqttGateway mqttGateWay;

    @Resource
    private LevelResultService levelResultService;



    /**
     * 处理接收到的数据
     *
     * @param port 串口
     * @param data 接收数据
     */
    @Override
    public void handlerSensorData(SerialPort port, String data) {
        boolean flag = true;

        // 收到数据后接着向串口发送命令测量下一个通道号
        if (passage < maxPassage + 1) {

            // 如果不是最后一个通道数据,则发送命令给仪器测量下一个通道数据
            String sendData;
            if (passage < 10) {
                sendData = String.format(":%s%s0%dFF\r\n", SerialPortServiceImp.deviceCode, fixedCommand, passage);
            } else {
                sendData = String.format(":%s%s%dFF\r\n", SerialPortServiceImp.deviceCode, fixedCommand, passage);
            }
            log.info("send data:" + sendData);
            byte[] sendDataBytes = sendData.getBytes();
            port.writeBytes(sendDataBytes, sendDataBytes.length);
        }
        // 通道号加1
        passage++;

        // 过滤错误数据
        if (data.charAt(7) == 'E' || data.charAt(15) == 'E') {
            flag = false;
        } else if (data.charAt(8) == '0' && data.charAt(9) == '0' && data.charAt(10) == '0' && data.charAt(11) == '0' && data.charAt(12) == '0' && data.charAt(13) == '0' && data.charAt(14) == '0') {
            flag = false;
        } else if (!SerialPortServiceImp.checkDataValid(data)) {
            // 数据中有不对的需要过滤
            flag = false;
        }
        // 取出通道号
        int index = Integer.parseInt(data.substring(5, 7));
        if (flag) {
            // 对应通道存入数据
            surveyDataList.set(index, data.trim());
        }
        if (passage == maxPassage + 2) {
            // 所用通道数据测量完毕,组织数据上传平台
            //获取当前时间戳
            long millis = System.currentTimeMillis();
            long timestamp = millis / 1000;
            // 拼接上传测量数据
            StringBuilder surveyDataBuilder = new StringBuilder("dtutime:").append(timestamp).append(",");
            List<LevelResult> saveList = new ArrayList<>();
            // Date surveyTime = new Date();
            String surveyTime = Instant.ofEpochMilli(millis)
                    .atZone(ZoneId.systemDefault())
                    .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            for (String surveyData : surveyDataList) {
                if (surveyData != null) {
                    LevelResult levelResult = new LevelResult();
                    levelResult.setSensorNo(surveyData.substring(5, 7));
                    levelResult.setSurveyTime(surveyTime);
                    levelResult.setUploadStatus(0);
                    levelResult.setSurveyData(surveyData);
                    levelResult.setTaskId(timestamp);
                    saveList.add(levelResult);
                    surveyDataBuilder.append(surveyData).append(",");
                }
            }
            // 去掉末尾逗号
            if (surveyDataBuilder.charAt(surveyDataBuilder.length() - 1) == ',') {
                surveyDataBuilder.deleteCharAt(surveyDataBuilder.length() - 1);
            }
            // 保存数据

            levelResultService.saveBatch(saveList);
            // 上传数据
            UploadDataBo uploadData = new UploadDataBo(surveyDataBuilder.toString(), timestamp, DATA_TYPE, TRANSFER_MODULE_MAC);
            String uploadDataJson = JSONUtil.toJsonStr(uploadData);
            log.info("mqtt发送数据：topic:{},data:{}",MqttInBoundConfiguration.sendTopic,uploadData);
            // mqtt传递数据
            mqttGateWay.sendToMqtt(MqttInBoundConfiguration.sendTopic, uploadDataJson);
        }

    }


    /**
     * 处理接收到的mqtt数据
     *
     * @param data 接收到的数据
     */
    @Override
    public void handlerMqttData(String data) {
        JSONObject jsonObject = new JSONObject(data);
        String responseDataStr = jsonObject.getStr("data");
        log.info("接受到mqtt返回的数据------------->：{}",data);
        ResponseDataBo responseDataBo = JSONUtil.toBean(responseDataStr, new TypeReference<ResponseDataBo>() {
        }, true);
        if (!ObjectUtils.isEmpty(responseDataBo)) {
            if (responseDataBo.getIsModifyTime() == 1) {
                // 更新定时器间隔时长
            } else {
                if (responseDataBo.getHostname() != null && StringUtils.hasText(responseDataBo.getHostname())) {
                    // 从盒子转发数据到对接平台
                }
            }

            if (responseDataBo.getIsClear() == 1) {
                clearSurveyDataList();
            }
        }
    }

    @Override
    public void handlerMqttHistoricalDataData(List<Integer> taskIds) {
        log.info("接收到mqtt历史数据taskIds:{}",taskIds);
        if (CollUtil.isNotEmpty(taskIds)) {
            //将回执的ids改为已上传状态
            LambdaUpdateWrapper<LevelResult> lambdaUpdateWrapper = new LambdaUpdateWrapper<LevelResult>().set(LevelResult::getUploadStatus, 1).in(LevelResult::getTaskId, taskIds);
            levelResultService.update(lambdaUpdateWrapper);
        }
    }

    /**
     * 清空测量列表数据
     */
    private static void clearSurveyDataList() {
        // 集合列表所有置为null
        Collections.fill(surveyDataList, null);
    }

}
